﻿Imports System.Drawing
Imports System.Windows.Forms

<System.ComponentModel.DefaultEvent("TextChanged")> _
Public Class SearchBox
    Inherits System.Windows.Forms.TextBox

#Region "Declarations"
    Private Declare Function ShowWindow Lib "user32" (ByVal handle As IntPtr, ByVal nCmdShow As Integer) As Integer
    Private Const SW_SHOWNA As Integer = 8

    Dim popup As popup_Form
    Dim popHeigt As Integer = 200
    Public ReadOnly Property PopUpShown As Boolean
        Get
            If Me.popup IsNot Nothing Then
                Return Me.popup.Visible
            Else
                Return False
            End If
        End Get
    End Property
    Dim WithEvents frm As Form
    Public HidePopupOnFirstSelection As Boolean = False
    Public WithEvents PopupListBox As Abyx.WindowsExtendedControls.DetailListBox
    Public Event SelectedIndexChanged(sender As Object, e As System.EventArgs)
    Private iMouseOverPopup As Boolean = True
    Private iSelectedItem As Object
    Public Property SelectedItem As Object
        Get
            Return Me.iSelectedItem
        End Get
        Set(value As Object)
            Me.iSelectedItem = value
            Me.Text = ""
        End Set
    End Property
    Private imSettingText As Boolean = False
#End Region

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        ' Me.SetStyle(Windows.Forms.ControlStyles.SupportsTransparentBackColor, True)

        setupListBox()
        setupPopup()

    End Sub

#Region "Designer Generated Code"
    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
            If disposing AndAlso PopupListBox IsNot Nothing Then
                PopupListBox.Dispose()
                PopupListBox = Nothing
            End If
            If disposing AndAlso popup IsNot Nothing Then
                popup.Close()
                popup.Dispose()
                popup = Nothing
            End If
            If disposing AndAlso frm IsNot Nothing Then
                RemoveHandler frm.Move, AddressOf frm_Move
                frm.Close()
                frm.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private WithEvents components As System.Windows.Forms.TextBox

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.Windows.Forms.TextBox()
        Me.SuspendLayout()
        '
        'components
        '
        Me.components.Location = New System.Drawing.Point(0, 0)
        Me.components.Name = "TextBox"
        Me.components.Size = New System.Drawing.Size(100, 21)
        Me.components.TabIndex = 0
        '
        'TextBox
        '
        Me.Name = "TextBox"
        Me.ResumeLayout(False)
    End Sub
#End Region

    Private Sub OnSelectedIndexChanged(e As System.EventArgs)
        RaiseEvent SelectedIndexChanged(Me, e)
        If Me.PopUpShown Then togglePopUp()
    End Sub

    Protected Overrides Sub OnResize(e As System.EventArgs)
        If PopUpShown Then
            popup.Size = New Size(Me.Size.Width, popHeigt)
        End If
        MyBase.OnResize(e)
    End Sub

    Private Sub togglePopUp()
        If Me.PopUpShown Then
            Me.popup.Hide()
        Else
            setupPopup()
            If Me.Parent IsNot Nothing Then
                Dim sLoc As Point = Me.Parent.PointToScreen(Me.Location)
                Me.popup.Location = New Point(sLoc.X, sLoc.Y + Me.Height + 1)
                Me.popup.Size = New Size(Me.Size.Width, Me.popHeigt)
                ShowWindow(Me.popup.Handle, SW_SHOWNA)
                If frm IsNot Nothing Then frm.Activate()
                Me.Focus()
                Me.SelectionLength = 0
                Me.SelectionStart = Me.Text.Length
            End If
        End If
    End Sub

    Protected Overrides Sub OnParentChanged(e As System.EventArgs)
        frm = Me.FindForm
        If frm IsNot Nothing Then
            AddHandler frm.Move, AddressOf frm_Move
            'AddHandler frm.Deactivate, AddressOf frm_Deactivate
        End If
        MyBase.OnParentChanged(e)
    End Sub

    Private Sub setupListBox()
        Me.PopupListBox = New Abyx.WindowsExtendedControls.DetailListBox()
        Me.PopupListBox.Dock = System.Windows.Forms.DockStyle.Fill
        Me.PopupListBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable
        Me.PopupListBox.FormattingEnabled = True
        Me.PopupListBox.Location = New System.Drawing.Point(0, 0)
        Me.PopupListBox.Name = "DetailListBox1"
        Me.PopupListBox.Size = New System.Drawing.Size(336, 319)
        Me.PopupListBox.TabIndex = 0
        Me.PopupListBox.BackColor = SystemColors.InactiveBorder
        'AddHandler Me.PopupListBox.SelectedIndexChanged, AddressOf PopupListBox_SelectedIndexChanged
        'AddHandler Me.PopupListBox.DoubleClick, AddressOf SearchBox_DoubleClick
        'AddHandler Me.PopupListBox.MouseMove, AddressOf popup_MouseMove
    End Sub

    Private Sub setupPopup()
        If Me.popup Is Nothing Then
            Me.popup = New popup_Form(Me)
        End If

        Me.popup.SuspendLayout()
        Me.popup.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.popup.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.popup.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange
        Me.popup.CausesValidation = False
        Me.popup.StartPosition = FormStartPosition.Manual
        Me.popup.ClientSize = New System.Drawing.Size(336, 319)
        Me.popup.ControlBox = False
        Me.popup.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
        Me.popup.MaximizeBox = False
        Me.popup.MinimizeBox = False
        Me.popup.Name = "popup_Form"
        Me.popup.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
        Me.popup.TopMost = True
        Me.popup.Controls.Add(Me.PopupListBox)
        Me.popup.ResumeLayout()
    End Sub

    Private Sub SearchBox_DoubleClick(sender As Object, e As System.EventArgs) Handles Me.DoubleClick
        If PopupListBox.SelectedItem IsNot Nothing Then
            OnSelectedIndexChanged(e)
            If PopUpShown Then togglePopUp()
        End If
    End Sub

    Private Sub PopupListBox_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles PopupListBox.SelectedIndexChanged
        If PopupListBox.SelectedItem IsNot Nothing Then
            If PopUpShown AndAlso HidePopupOnFirstSelection Then togglePopUp()
            Me.iSelectedItem = PopupListBox.SelectedItem
            Me.imSettingText = True
            Me.Text = iSelectedItem.ToString
            Me.imSettingText = False
            OnSelectedIndexChanged(e)
        Else
            Me.iSelectedItem = Nothing
            OnSelectedIndexChanged(e)
        End If
    End Sub

    Protected Overrides Sub OnTextChanged(e As System.EventArgs)
        If imSettingText = False Then
            If Me.Text <> "" Then
                If Me.PopUpShown = False Then togglePopUp()
            Else
                If Me.PopUpShown = True Then togglePopUp()
            End If
        End If
        MyBase.OnTextChanged(e)
    End Sub

    Private Sub frm_Move(sender As Object, e As System.EventArgs)
        If Me.popup IsNot Nothing AndAlso Me.popup.Visible Then
            Debug.Print("Moving............")
            Dim sLoc As Point = Me.frm.PointToScreen(Me.Location)
            Me.popup.Location = New Point(sLoc.X, sLoc.Y + Me.Height + 1)
        End If

    End Sub

    Protected Overrides Sub OnClick(e As System.EventArgs)
        OnTextChanged(New System.EventArgs)
        If Me.PopUpShown = False Then togglePopUp()
        MyBase.OnClick(e)
    End Sub

    Protected Overrides Sub OnGotFocus(e As System.EventArgs)
        If Me.Text <> "" Then
            Me.SelectionStart = 0
            Me.SelectionLength = Me.Text.Length
        End If
        MyBase.OnGotFocus(e)
    End Sub

    Protected Overrides Sub OnLeave(e As System.EventArgs)
        If Me.PopUpShown AndAlso iMouseOverPopup = False Then togglePopUp()
        MyBase.OnLeave(e)
    End Sub

    Protected Overrides Sub OnKeyPress(e As System.Windows.Forms.KeyPressEventArgs)
        If Me.PopUpShown Then
            'SendKeys.Send("{ENTER}")
        End If
        MyBase.OnKeyPress(e)
    End Sub

End Class
